/*! \file HXWindow.h
    \brief Head X graphical user interface.

	Head X | Flinders University | Martin Luerssen & Trent Lewis | 2009+
*/

#pragma once

class HXMainWindow;
class HXLogger;
class HXSubtitle;

#include "HXPlayer.h"
#include <time.h> // for HXSubtitles::Prepare and HXLogger

//-----------------------------------------------------------------------------

#define MAX_STATUS_LENGTH 1024

typedef unsigned __int32 HXWindowToggle;
const HXWindowToggle HXWT_NORMAL = 0x00000000;
const HXWindowToggle HXWT_MENU = 0x00000001;
const HXWindowToggle HXWT_MAXIMIZE = 0x00000002;
const HXWindowToggle HXWT_BORDER = 0x00000004;
const HXWindowToggle HXWT_FULLSCREEN = 0x00000007;
const HXWindowToggle HXWT_TRANSPARENT = 0x00000010;

extern HWND g_keyInputDlg;

//-----------------------------------------------------------------------------

INT_PTR CALLBACK	DialogChangeVoice(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK	DialogDirectSpeak(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK	DialogAbout(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK	DialogSynapseID(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

//-----------------------------------------------------------------------------

class HXMainWindow
{
public:
	HXMainWindow();
	bool	Create(int nCmdShow);
	void	Destroy();
	HWND	GetMainHandle() const { return m_hFramedWnd; }
	HWND	GetLayerHandle() const  { return m_hLayerWnd; }
	HWND	GetStatHandle() const { return m_hStatWnd; }
	void	ShowStatus(const wchar_t* a_Text, ...);
	void	ShowErrorStatus(const wchar_t* a_Text, ...);

	void	RelativeResize(int width, int height);
	void	Resize(int width, int height);
	void	RelativeReposition(int x, int y);
	void	Reposition(int x, int y);
	
	bool	StartupConfigOpen();
	void	ClickConfigOpen();
	void	ClickConfigReopen();
	void	ClickParamOpen();
	void	ClickParamReopen();
	void	ClickConfigClear();
	void	ClickBackgroundOpen();
	void	ClickBackgroundClear();
	void	ClickModelAdd();
	void	ClickModelClear();
	void	ClickModelRemove(int id);
	void	UpdateModelsMenu();
	void	ClickModelsExport();

	void	UpdateQuickMenu();
	void	ClickSubtitle(bool isInputPrompt);
	void	ClickSetEchoInputs();
	void	ClickParseInput();
	void	ClickBreakOnStop();
	void	ClickSynapse(int menu_id = 0);
	void	ClickSynapseID();
	void	ClickDirectSpeak();
	void	ClickChangeVoice();	
	void    SelectTTSEngine(int engineid);
	void	ClickSetIdle();
	
	void	PressEscape();
	void	ClickWindowToggle(HXWindowToggle tog);
	void	ClickBringToTop();
	void	ClickMouseMode(HXMouseMode mm);
	void	UpdateViewMenu();

	void	ClickAbout();

	void	ApplyCurrentConfig();

	void	WindowStatus();

protected:
	static HWND CreateStatusBar(HWND hwndParent, int nStatusID, HINSTANCE hinst, int nParts);
	
	HMENU GetFileMenu() { return GetSubMenu(GetMenu(m_hFramedWnd), 0); }
	HMENU GetModelMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 0), 3); }
	HMENU GetModelsMenu() { return GetSubMenu(GetModelMenu(), 1); }
	HMENU GetTransformMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 0), 4); }
	HMENU GetActionMenu() { return GetSubMenu(GetMenu(m_hFramedWnd), 1); }
	HMENU GetQuickActionMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 1), 1); }
	HMENU GetSubtitleMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 1), 2); }
	HMENU GetSynapseMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 2), 0); }
	HMENU GetMouseMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 2), 2); }
	HMENU GetWindowMenu() { return GetSubMenu(GetSubMenu(GetMenu(m_hFramedWnd), 2), 3); }

	HWND m_hFramedWnd;							// main program window
	HWND m_hLayerWnd;							// alternate layered window for transparent background rendering
	HWND m_hStatWnd;							// status subwindow
	HMENU m_hMenu;								// menu subwindow (temporary storage only)
	bool m_bFullscreen;							// true if window maximized
	bool m_bWindowHasBorder;					// true if window has border
	bool m_bWindowOnTop;						// true if window is topmost
	wchar_t m_statusBuffer[MAX_STATUS_LENGTH];	// stores the last status message
};

//-----------------------------------------------------------------------------

class HXLogger
{
public:
	HXLogger();
	~HXLogger();
	bool Open(wstring& filename);
	bool Close();
	void Log(const string& text, wchar_t logtype);
	void Log(const char* text, wchar_t logtype);
	void Log(const wstring& text, wchar_t logtype);
	void Log(const wchar_t* text, wchar_t logtype);
private:
	clock_t m_startClock;	// time since logger creation
	HANDLE  m_logFile;		// optional I/O file
	wchar_t m_logBuffer[MAX_TEXT_LENGTH]; // temporary log entry storage
	HANDLE m_hLogMutex;	// log thread mutex
};

//-----------------------------------------------------------------------------

#define SUBTITLE_DEFAULT_XPOS 0.0f
#define SUBTITLE_DEFAULT_YPOS -160.0f
#define SUBTITLE_DEFAULT_ZPOS 100.0f
#define SUBTITLE_DEFAULT_LENGTH 40
#define SUBTITLE_DEFAULT_BLINKRATE 500
#define SUBTITLE_DEFAULT_FONTSIZE 22

class HXSubtitle
{
public:
	HXSubtitle();
	void Clear() { m_subtitle[0] = 0; }
	void Generate();

	void PromptKey(char charcode);
	void PromptBack();
	void PromptEnter();

	void SetSubtitleSpokenRatio(const wstring& subtitle, const wstring& spoken);
	void SetSubtitleSpokenRatio(float ratio) { m_subSpokenRatio = ratio; }

	void SetSpoken(string text) { m_spokenText = text; }
	wchar_t* GetText() { return m_subtitle; }
	size_t Length() { return m_subtitleLength; }
	
private:
	wchar_t m_subtitle[MAX_TEXT_LENGTH];		// stores the subtitle (what is displayed)
	size_t m_subtitleLength;					// current length of subtitle
	wchar_t m_subtitlePrompt[MAX_TEXT_LENGTH];	// stores the subtitle input prompt (what is typed)
	int m_subtitlePromptLength;					// length of the input prompt
	long m_subtitleClock;						// last time subtitle has been updated
	string m_spokenText;						// the full spoken text
	float m_subSpokenRatio;						// ratio of length of subtitle against length of spoken text
};

//=============================================================================

extern HXMainWindow g_window;
extern HXLogger g_logger;
extern HXSubtitle g_subtitle;

